//
// Created by Hi on 25-7-22.
//

#include "FileUtils.h"

#include <algorithm>
#include <chrono>
#include <fstream>

#include "MyArray.h"
#include "TimeUtils.h"
#include "../ManageStu.h"
#include "../entity/Student.h"
#include "../concurrent/ThreadPool.h"
#include "../context/UserContext.h"
#include "../entity/Graduate.h"
#include "../exception/CustomException.h"
#include "../entity/Undergraduate.h"

using namespace std;
using namespace gao;

void FileUtils::loadAllStus(vector<unique_ptr<Student>>& arr, unordered_set<int>& m_set) {
    ifstream m_file;
    try {
        m_file.open("E:\\C++Project\\studentManage\\database\\studentInfo", ios::in);
    }catch (CustomException &e) {
        ThreadPool* threadPool=ThreadPool::getInstance();
        threadPool->addTask([&]() {
            logAccess(e.what(),false, UserContext::getCurrentUser());
        });
        cerr << e.what() << endl;
        return;
    }
    if (!m_file.is_open()) {
        cerr << "Error: File not open!" << endl;
        return;
    }
    string line;
    while (getline(m_file, line)) {
        cout << "Read line: " << line << endl;
        unique_ptr<Student> student;
        if (line.find("Teacher") != std::string::npos) {
            student = make_unique<Graduate>();
        } else {
            student = make_unique<Undergraduate>();
        }
        student->deserialize(line);
        m_set.insert(student->getId());
        arr.push_back(move(student));
    }
    m_file.close();
}

void FileUtils::saveAllStus(const vector<unique_ptr<Student>>& arr) {
    ofstream m_file;
    try {
        m_file.open("E:\\C++Project\\studentManage\\database\\studentInfo", ios::out | ios::trunc);
    }catch (CustomException &e) {
        ThreadPool* threadPool=ThreadPool::getInstance();
        auto current_user = UserContext::getCurrentUser();
        threadPool->addTask([&e,&current_user]() {
            logAccess(e.what(),false, current_user);
        });
        cerr << e.what() << endl;
        return;
    }

    if (!m_file.is_open()) {
        cerr << "Error: File not open!" << endl;
        return;
    }
    for (const auto& student : arr) {
        m_file << student->serialize() << endl;
    }
    m_file.close();
}


void FileUtils::logAccess(const string& info,bool type,const UserContext::userInfo& user) {
    fstream m_file;
    string current_time_string = TimeUtils::getCurrentTimeString();
    string path;
    // 记录访问日志
    if (type) {
       path="E:\\C++Project\\studentManage\\database\\access_log";
    }else {
        // 错误日志
        path="E:\\C++Project\\studentManage\\database\\error_log";
    }
    try {
        m_file.open(path,ios::app);
        if (!m_file.is_open()) {
            throw CustomException("打开文件失败", CustomException::FILE_ERROR);
        }
    }catch (CustomException &e) {
        cerr<<e.what()<<endl;
    }
    // 获取当前时间打印;
    m_file<<"Access At Time{"+current_time_string+"},The operation is {"+info<<"} by the operator {" +user.toString()<<"}"<<endl;
    m_file.close();
}

// void FileUtils::build_index(const string& data_file, const string& index_file) {
//     ifstream data(data_file);  // 默认文本模式
//     ofstream index(index_file);
//     if (!data || !index) return;
//
//     long long offset = 0;
//     int line_number = 1;
//     string line;
//
//     // 写入第一行索引
//     index << line_number << " " << offset << "\n";
//
//     while (getline(data, line)) {
//         offset=0;
//         // 计算下一行的起始位置
//         offset += line.size() + 1; // +1 是换行符的长度
//         index << (++line_number) << " " << offset << "\n";
//     }
// }
// // 从文本索引文件中读取指定行范围的偏移量
// vector<FileUtils::LineIndex> FileUtils::read_indices_in_range(
//     const string& index_file,
//     int start_line,
//     int end_line) {
//     vector<LineIndex> result;
//     ifstream index(index_file);
//     if (!index) return result;
//
//     string line;
//     while (getline(index, line)) {
//         int line_num;
//         long long offset;
//         istringstream iss(line);
//         if (iss >> line_num >> offset) {
//             if (line_num >= start_line && line_num <= end_line) {
//                 result.push_back({offset, line_num});
//             } else if (line_num > end_line) {
//                 break;  // 已超出范围，提前结束
//             }
//         }
//     }
//     return result;
// }
//
// vector<Student*> FileUtils::read_line(const string& data_file, const string& index_file, int target_line,int count) {
//     ifstream index(index_file);
//     ifstream data(data_file);
//     if (!index.is_open()||!data.is_open()) {
//         throw CustomException("无法打开索引文件", CustomException::FILE_ERROR);
//     }
//
//     // 计算目标行在索引文件中的位置
//     size_t index_offset = (target_line - 1) * sizeof(LineIndex);
//     index.seekg(index_offset);
//     string line;
//     int line_num;
//     long long offset;
//     getline(index, line);
//     istringstream iss(line);
//     iss >> line_num >> offset;
//     cout<<line_num<<offset<<endl;
//
//
//     data.seekg(offset);
//     int i=0;
//     vector<Student*> students;
//     students.resize(count+1);
//     while (i++<count) {
//         string dataline;
//         if (!getline(data, dataline))
//             break;
//         if (dataline.find("Teacher")!= std::string::npos) {
//             Student* student=new Graduate();
//             student->deserialize(dataline);
//             students.emplace_back(student);
//         }else {
//             Student* student=new Undergraduate();
//             student->deserialize(dataline);
//             students.emplace_back(student);
//         }
//     }
//     return students;
// }
